package utils

import (
	"KumquatDrivesServices/StorageEngine"
	"KumquatDrivesServices/enums"
	"KumquatDrivesServices/model"
	"archive/zip"
	"bytes"
	"fmt"
	"io"
	"path"
)

type FileTree struct {
	FileId   model.SnowflakeIdType
	FilePid  model.SnowflakeIdType
	FileName string
	FilePath string
	IsFolder bool
	Children []*FileTree
}

// BuildFileTree 将文件列表转换为树形结构
func BuildFileTree(files []model.FileModel) []*FileTree {
	// 创建哈希表，用于快速查找节点
	nodeMap := make(map[model.SnowflakeIdType]*FileTree)
	// 初始化所有节点并存入哈希表
	for i := range files {
		node := &FileTree{
			FileId:   files[i].ID,
			FilePid:  files[i].FilePid,
			FileName: files[i].FileName,
			FilePath: files[i].FilePath,
			IsFolder: files[i].IsFolder,
			Children: []*FileTree{},
		}
		nodeMap[node.FileId] = node
	}

	// 构建树形结构
	var rootNodes []*FileTree
	for _, node := range nodeMap {
		parentID := node.FilePid
		// 如果父节点是根（例如 filePid=1），直接加入根列表
		if _, ok := nodeMap[parentID]; !ok {
			rootNodes = append(rootNodes, node)
			continue
		}
		// 否则找到父节点并挂载到其子节点列表
		if parent, exists := nodeMap[parentID]; exists {
			parent.Children = append(parent.Children, node)
		}
	}

	return rootNodes
}

// GenerateZipFromStruct 生成ZIP压缩包
func GenerateZipFromStruct(files []*FileTree) ([]byte, error) {
	var buf bytes.Buffer
	zipWriter := zip.NewWriter(&buf)

	var writeZipEntry func(f *FileTree, pathPrefix string) error
	writeZipEntry = func(f *FileTree, pathPrefix string) error {
		var fullPath string
		if pathPrefix == "" {
			fullPath = f.FileName
		} else {
			fullPath = path.Join(pathPrefix, f.FileName)
		}

		if f.IsFolder == enums.File {
			fileData, err := StorageEngine.Engine.GetFile(f.FilePath, f.FileName)
			if err != nil {
				return fmt.Errorf("读取文件 %s 失败: %v", f.FileName, err)
			}
			zipEntry, err := zipWriter.Create(fullPath)
			if err != nil {
				return fmt.Errorf("创建ZIP条目 %s 失败: %v", fullPath, err)
			}
			_, err = io.Copy(zipEntry, bytes.NewReader(fileData))
			if err != nil {
				return fmt.Errorf("复制文件 %s 到ZIP失败: %v", fullPath, err)
			}
		} else { // 处理文件夹
			// 创建目录条目
			_, err := zipWriter.Create(fullPath + "/")
			if err != nil {
				return fmt.Errorf("创建目录条目 %s 失败: %v", fullPath, err)
			}
			// 递归处理子节点
			for _, child := range f.Children {
				err := writeZipEntry(child, fullPath)
				if err != nil {
					return err
				}
			}
		}
		return nil
	}

	for _, file := range files {
		err := writeZipEntry(file, "")
		if err != nil {
			return nil, err
		}
	}

	if err := zipWriter.Close(); err != nil {
		return nil, fmt.Errorf("关闭ZIP写入器失败: %v", err)
	}
	return buf.Bytes(), nil
}

// GenerateFileFromStruct 生成文件
func GenerateFileFromStruct(files []*FileTree) ([]byte, error) {
	if len(files) != 1 {
		return nil, fmt.Errorf("应为单个文件")
	}
	file := files[0]
	if file.IsFolder != enums.File {
		return nil, fmt.Errorf("应为文件")
	}
	return StorageEngine.Engine.GetFile(file.FilePath, file.FileName)
}
